#include <stx/test/test.hpp>

TEST_CASE (core_regex)
{
    CHECK(isMatch("Hello"sv, makeRegex(R"(^.+ll.+$)"sv)));
    CHECK(isMatch(L"Hello"sv, makeRegex(LR"(^.+ll.+$)"sv)));
    CHECK(isMatch("Hello"sv, rgx<R"(^.+ll.+$)">()));
    CHECK(isMatch(L"Hello"sv, rgx<LR"(^.+ll.+$)">()));

    CHECK(!isMatch("Hello"sv, makeRegex(R"(^.+ok.+$)"sv)));
    CHECK(!isMatch(L"Hello"sv, makeRegex(LR"(^.+ok.+$)"sv)));
    CHECK(!isMatch("Hello"sv, rgx<R"(^.+ok.+$)">()));
    CHECK(!isMatch(L"Hello"sv, rgx<LR"(^.+ok.+$)">()));

    {
        auto mr = getMatchResults(
            "heliilo"sv, rgx<R"(^h([aeiou]+)l([aeiou]+)l([aeiou]+)$)">());
        CHECK(mr.size() == 4);
        CHECK(mr[0] == "heliilo"sv);
        CHECK(mr[1] == "e"sv);
        CHECK(mr[2] == "ii"sv);
        CHECK(mr[3] == "o"sv);
    }

    {
        auto mr = getMatchResults(
            L"heliilo"sv, rgx<LR"(^h([aeiou]+)l([aeiou]+)l([aeiou]+)$)">());
        CHECK(mr.size() == 4);
        CHECK(mr[0] == L"heliilo"sv);
        CHECK(mr[1] == L"e"sv);
        CHECK(mr[2] == L"ii"sv);
        CHECK(mr[3] == L"o"sv);
    }

    CHECK("hewwwowwwo"sv ==
          regexReplace("hellollo"sv, rgx<R"(ll)">(), "www"_sv));
    CHECK(L"hewwwowwwo"sv ==
          regexReplace(L"hellollo"sv, rgx<LR"(ll)">(), L"www"_sv));

    {
        auto rng = regexSearch("hellollo"sv, rgx<R"((.)\1)">(), 0);
        auto pos = rng.begin();
        CHECK("ll"sv == *pos);
        ++pos;
        CHECK("ll"sv == *pos);
        ++pos;
        CHECK(rng.end() == pos);
    }

    {
        auto rng = regexSearch(L"hellollo"sv, rgx<LR"((.)\1)">(), 0);
        auto pos = rng.begin();
        CHECK(L"ll"sv == *pos);
        ++pos;
        CHECK(L"ll"sv == *pos);
        ++pos;
        CHECK(rng.end() == pos);
    }

    {
        auto rng = regexSearch("hellollo"sv, rgx<R"((.)\1(?=o))">(), 0);
        auto pos = rng.begin();
        CHECK("ll"sv == *pos);
        ++pos;
        CHECK("ll"sv == *pos);
        ++pos;
        CHECK(rng.end() == pos);
    }

    {
        auto rng = regexSearch(L"hellollo"sv, rgx<LR"((.)\1(?=o))">(), 0);
        auto pos = rng.begin();
        CHECK(L"ll"sv == *pos);
        ++pos;
        CHECK(L"ll"sv == *pos);
        ++pos;
        CHECK(rng.end() == pos);
    }

    CHECK("el"sv == regexSearchFirst("hellollo"sv, rgx<R"([aeiou]l)">(), 0));
    CHECK(L"el"sv == regexSearchFirst(L"hellollo"sv, rgx<LR"([aeiou]l)">(), 0));

    CHECK(ranges::equal(split("##abc#xyz#"sv, rgx<"#">()),
                        std::vector{""s, ""s, "abc"s, "xyz"s}));
    CHECK(ranges::equal(split("##abc#xyz"sv, rgx<"#">()),
                        std::vector{""s, ""s, "abc"s, "xyz"s}));

    CHECK(ranges::equal(split(L"##abc#xyz#"sv, rgx<L"#">()),
                        std::vector{L""s, L""s, L"abc"s, L"xyz"s}));
    CHECK(ranges::equal(split(L"##abc#xyz"sv, rgx<L"#">()),
                        std::vector{L""s, L""s, L"abc"s, L"xyz"s}));

    CHECK(isNaturalNumber("0"sv));
    CHECK(isNaturalNumber("123"sv));
    CHECK(!isNaturalNumber("-123"sv));
    CHECK(!isNaturalNumber("123.3234"sv));

    CHECK(isIp4("13.32.54.234"sv));
    CHECK(!isIp4("13.32.54.256"sv));
    CHECK(isIp6("FE80:0000:0000:0000:0202:B3FF:FE1E:8329"sv));
    CHECK(!isIp6("FE80:0000:0000:0000:0202:B3FF:FE1E:G329"sv));
    CHECK(isIp6("::1"sv));
}